package pogvue.datamodel;


import java.util.*;
import pogvue.analysis.*;


public class PwmCluster {

    Vector pwms;
    double pwm[];
    int seqlen;

    Vector matches = null;

    public PwmCluster(Pwm pwm) {
	pwms = new Vector();

	addPwm(pwm);

    }

    public void addMatch(TFMatrix tfm) {
	if (matches == null) {
	    matches = new Vector();
	}
	if (!matches.contains(tfm)) {
	    matches.addElement(tfm);
	}
    }
  public int size() {
    return pwms.size();
  }
  public boolean contains(Pwm pwm) {

	for (int i = 0; i < pwms.size(); i++) {
	    Pwm tmp = (Pwm)pwms.elementAt(i);

	    ChrRegion reg1 = tmp.getChrRegion();
	    ChrRegion reg2 = pwm.getChrRegion();

	    if (reg1 != null && reg2 != null) {

		if (reg1.getChr().equals(reg2.getChr()) &&
		    reg1.getStart() == reg2.getStart() &&
		    reg1.getEnd()   == reg2.getEnd()) {

		    System.out.println("Found matching pwm " + reg1.toString() + " " + reg2.toString());
		    return true;
		}
	    }
	}
	return false;
    }
    public void addPwm(Pwm newpwm) {

	if (contains(newpwm)) {
	    System.out.println("cluster contains pwm");
	    return;
	}


        //System.out.println("Adding Pwm " + newpwm.getPwm().length/4 + " " + PwmCluster.getConsensus(newpwm.getPwm()));

	if (pwms.size() == 0) {
	    seqlen = newpwm.getPwm().length/4;
	    pwm = new double[newpwm.getPwm().length];
	}

	int num = pwms.size();
	    
	int i = 0;
	
	while (i < seqlen) {
	    int j = 0;
	    
	    while (j < 4) {
		pwm[i*4+j] *= num;
		pwm[i*4+j] += newpwm.getPwm()[i*4+j];
		pwm[i*4+j] /= (num+1);
		j++;
	    }
	    i++;
	}
	pwms.addElement(newpwm);
    }
    public double[] getPwm() {
	return pwm;
    }

    public Vector getPwms() {
	return pwms;
    }

    public static String getConsensus(double[] pwm) {
	StringBuffer cons = new StringBuffer();

	int i = 0;
	
	while (i < pwm.length/4) {
	    double maxval = 0.25;
	    String maxch  = "-";
	    
	    if (pwm[i*4] > maxval) {
		maxval = pwm[i*4];
		maxch = "A";
	    } 

	    if (pwm[i*4+1] > maxval) {
		maxval = pwm[i*4+1];
		maxch  = "T";
	    } 
	    if (pwm[i*4+2] > maxval) {
		maxval = pwm[i*4+2];
		maxch  = "C";
	    } 
	    if (pwm[i*4+3] > maxval) {
		maxval = pwm[i*4+3];
		maxch  = "G";
	    }
	    cons.append(maxch);
	    i++;
	}
	return cons.toString();
    }

  public void print() {
    Vector  pwms = getPwms();
	    
    System.out.print("Cluster\t" + pwms.size() + "\t");

    String matchstr = "";

    if (matches != null) {
	for (int i = 0;i < matches.size(); i++) {
	    matchstr += "_" + ((TFMatrix)matches.elementAt(i)).getName();
	}
    } else {
	matchstr = "-";
    }
	
    System.out.print(matchstr + "\t");

    System.out.print(getConsensus(getPwm()));
	    
    for (int j = 0; j < pwms.size(); j++) {
      Pwm p = (Pwm)pwms.elementAt(j);
      //System.out.print("\t" + p.getChrRegion().toString() + "\t" + PwmCluster.getConsensus(((Pwm)pwms.elementAt(j)).getPwm()));
      System.out.print("\t" + PwmCluster.getConsensus(((Pwm)pwms.elementAt(j)).getPwm()));
    }
	    
    System.out.print("\n");

    Correlation4.printPWM(getPwm(),true);
    System.out.println();
	    
    Pwm.printLogo(getPwm());
    
    System.out.println();
    System.out.println(PwmCluster.getConsensus(getPwm()));
    System.out.println();

  }
}


    
